package com.neusoft.databus.agent.config;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
@Component
@ConfigurationProperties(prefix = "databus.agent", ignoreUnknownFields = true)
public class DatabusAgentProperties {

    private final Pool pool = new Pool();
    private final SnmpTrap snmpTrap = new SnmpTrap();
    private final Modbus modbus = new Modbus();
    private final Snmp snmp = new Snmp();

    private final FlumeChannel flumeChannel = new FlumeChannel();
    private final FlumeSink flumeSink = new FlumeSink();
    @Getter
    @Setter
    private String flumeProcessorType = "default";

    @Getter
    @Setter
    public static class Pool {
        private final SocketPool socket = new SocketPool();
        private final Socket2Pool socket2 = new Socket2Pool();
        private final SnmpPool snmp = new SnmpPool();
        private final SerialPool serial = new SerialPool();
        private final OpcPool opc = new OpcPool();
        private final NettyPool netty = new NettyPool();
    }

    @Getter
    @Setter
    public static class SnmpTrap {
        private final SnmpTrapServer server = new SnmpTrapServer();
    }

    @Getter
    @Setter
    public static class Modbus {
        private boolean rtuCrcCheck = false;
    }

    @Getter
    @Setter
    public static class Snmp {
        //batched pdu one time
        private int pduBatchSize = 1;
        //parse integer value by bit referenced byte size
        private int binaryReferenceBytes = 1;
    }

    @Getter
    @Setter
    public static class SocketPool {
        // 允许创建资源的最大数量
        private int maxTotal = 24;
        //private int maxTotalPerKey = 1;
        // 当资源耗尽时，是否阻塞等待获取资源
        private boolean blockWhenExhausted = true;
        // 获取资源时的等待时间，单位毫秒。当 blockWhenExhausted 配置为 true 时，此值有效
        private long maxWaitMillis = 1000 * 10;
        // 当创建资源时会调用 factory.validateObject() 方法
        private boolean testOnCreate = true;
        // 每次从池中获取资源时都会调用 factory.validateObject() 方法
        private boolean testOnBorrow = true;
        // 回收资源线程的执行周期，单位毫秒。默认值 -1 ，-1 表示不启用线程回收资源
        private long timeBetweenEvictionRunsMillis = -1;
        // 资源最小空闲时间， 默认值 1800000，单位 毫秒
        private long minEvictableIdleTimeMillis = 1000 * 60 * 30;
    }

    @Getter
    @Setter
    public static class Socket2Pool {
        // 允许创建资源的最大数量
        private int maxTotal = 24;
        private int maxTotalPerKey = 1;
        // 当资源耗尽时，是否阻塞等待获取资源
        private boolean blockWhenExhausted = true;
        // 获取资源时的等待时间，单位毫秒。当 blockWhenExhausted 配置为 true 时，此值有效
        private long maxWaitMillis = 1000 * 10;
        // 当创建资源时会调用 factory.validateObject() 方法
        private boolean testOnCreate = true;
        // 每次从池中获取资源时都会调用 factory.validateObject() 方法
        private boolean testOnBorrow = true;
        // 回收资源线程的执行周期，单位毫秒。默认值 -1 ，-1 表示不启用线程回收资源
        private long timeBetweenEvictionRunsMillis = -1;
        // 资源最小空闲时间， 默认值 1800000，单位 毫秒
        private long minEvictableIdleTimeMillis = 1000 * 60 * 30;
    }

    @Getter
    @Setter
    public static class SnmpPool {
        private int maxTotal = 24;
        private int maxTotalPerKey = 8;
        private boolean blockWhenExhausted = true;
        private long maxWaitMillis = 1000 * 10;
        private boolean testOnCreate = true;
        private boolean testOnBorrow = true;
        private long timeBetweenEvictionRunsMillis = -1;
        private long minEvictableIdleTimeMillis = 1000L * 60L * 30L;
    }

    @Getter
    @Setter
    public static class SerialPool {
        private int maxTotal = 24;
        private int maxTotalPerKey = 1;
        private boolean blockWhenExhausted = true;
        private long maxWaitMillis = 1000 * 10;
        private boolean testOnCreate = true;
        private boolean testOnBorrow = true;
        private long timeBetweenEvictionRunsMillis = -1;
        private long minEvictableIdleTimeMillis = 1000L * 60L * 30L;
    }

    @Getter
    @Setter
    public static class OpcPool {
        private int maxTotal = 24;
        private int maxTotalPerKey = 8;
        private boolean blockWhenExhausted = true;
        private long maxWaitMillis = 1000 * 10;
        private boolean testOnCreate = true;
        private boolean testOnBorrow = true;
        private long timeBetweenEvictionRunsMillis = -1;
        private long minEvictableIdleTimeMillis = 1000L * 60L * 30L;
    }

    @Getter
    @Setter
    public static class NettyPool {
        // 允许创建资源的最大数量
        private int maxTotal = 24;
        private int maxTotalPerKey = 1;
        // 当资源耗尽时，是否阻塞等待获取资源
        private boolean blockWhenExhausted = true;
        // 获取资源时的等待时间，单位毫秒。当 blockWhenExhausted 配置为 true 时，此值有效
        private long maxWaitMillis = 1000 * 10;
        // 当创建资源时会调用 factory.validateObject() 方法
        private boolean testOnCreate = true;
        // 每次从池中获取资源时都会调用 factory.validateObject() 方法
        private boolean testOnBorrow = true;
        // 回收资源线程的执行周期，单位毫秒。默认值 -1 ，-1 表示不启用线程回收资源
        private long timeBetweenEvictionRunsMillis = -1;
        // 资源最小空闲时间， 默认值 1800000，单位 毫秒
        private long minEvictableIdleTimeMillis = 1000 * 60 * 30;
    }

    @Getter
    @Setter
    public static class SnmpTrapServer {
        private boolean disabled = false;
        private String address = "0.0.0.0";
        private int port = 162;
        private int threadPoolSize = 6;
        private int blockingQueueSize = 10000;
        private boolean l2CacheProvider = false;
        private String l2CacheTopic = "snmptrap-cache-topic";
        private String toPolicyTopic = "policy-snmptrap-topic";
        private String community = "public";
    }

    @Getter
    @Setter
    public static class FlumeChannel {
        private String capacity = "100000";
        private String transactionCapacity = "5000";
        private String keepAlive = "3";
    }

    @Getter
    @Setter
    public static class FlumeSink {
        private String avroRpcServer = "127.0.0.1:6666";
        private String batchSize = "100";
        private String connectionTimeout = "20000";
        private String requestTimeout = "60000";
    }
}
